<?php

/**
 * @author yxt 2012年11月14日11:38:56
 * 信息包内容基础业务
 */
include_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'nl_common.func.php';
//$GLOBALS['obj'][] = new nl_topic_item();
/**
 * 信息包内容基本业务
 */
class nl_topic_item {
	//当前调用方法产生的sql语句,一个方法可能有多个sql供调试使用
	static public $sql_arr = array ();
	//排序规则
	static public $order = array (
		NL_ORDER_NUM_ASC => " order by  nns_order asc ",
		NL_ORDER_NUM_DESC => " order by  nns_order desc ",
		NL_ORDER_TIME_ASC => " order by  nns_create_time asc ",
		NL_ORDER_TIME_DESC=> " order by  nns_create_time desc ",
		NL_ORDER_CLICK_ASC => " order by  nns_click asc ",
		NL_ORDER_CLICK_DESC => " order by  nns_click desc ",
		NL_ORDER_TIME_AND_NUM_DESC => ' order by nns_create_time_ex DESC, nns_audit DESC, nns_order DESC',
	);
	//可能有的组合查询使用|和#分割的
	static public $arr_com = array (
		"topic_id" => "",
		"category_id" => "",
		"keyword" => "",
		"tag" => ""
	);
	//采用like匹配的数组
	static public $arr_like = array (
		"title" => "",
		"subtitle" => "",
		"summary" => "",
		"source" => "",
		"content" => ""
	);
	//采用等号匹配的数组
	static public $arr_eq = array (
		"link_type" => ""
	);
	//缓存设置时间
	const CACHE_TIME_OUT = 300;
	/**
	 * 前端使用
	 * 前端从DC模块获取栏目下信息内容列表 只读取前端列表需要的字段。
	 * @param dc DC模块
	 * @param string 信息包ID
	 * @param string 信息包栏目ID，默认为1000
	 * @param string  tag epg输出标识
	 * @param int 起始查询记录位置
	 * @param int 查询记录条数
	 *@param string 排序规则，NL_ORDER_NUM_ASC | NL_ORDER_NUM_DESC | NL_ORDER_TIME_ASC | NL_ORDER_TIME_DESC | NL_ORDER_CLICK_ASC | NL_ORDER_CLICK_DESC
	 * @param String
	 * @param int 0模糊查询 1等于查询 $if_like
	 * @param array $field:获取完整字段，一维索引数组(后来加的，不影响之前的)
	 * @return *
	 * 			Array 信息包内容列表结果
	 * 			FALSE 查询失败
	 * 			TRUE  查询成功，但无数据
	 */

	static function epg_get_topic_item_list($dc, $topic_id, $category_id, $tag, $since, $num, $order = NL_ORDER_NUM_DESC, $policy = NL_DC_AUTO,$if_like=1, $fields = array ()) {
		$result = "";
		switch ($policy) {
			case NL_DC_AUTO :
				$result = self :: _epg_get_topic_item_list_cache($dc, $topic_id, $category_id, $tag, $since, $num, $order, $policy,$if_like,$fields);
				break;
			case NL_DC_DB :
				$result = self :: _epg_get_topic_item_list_db($dc->db(), $topic_id, $category_id, $tag, $since, $num, $order,$if_like, $fields);
				break;
			case NL_DC_CACHE :
				$result = self :: _epg_get_topic_item_list_cache($dc, $topic_id, $category_id, $tag, $since, $num, $order, $policy, $if_like,$fields);
				break;
		}
		return $result;
	}
	/**
	 * 从数据库直接读取栏目下信息内容列表
	 */
	static private function _epg_get_topic_item_list_db($db, $topic_id, $category_id, $tags, $since = null, $num, $order = NL_ORDER_NUM_DESC, $if_like=1,$fields = array ()) {
		//设置limit
		if ($since === null) {
			$limit = "";
		} else
			if (!empty ($since) && empty ($num)) {
				$limit = " LIMIT {$since}";
			} else {
				$limit = " LIMIT {$since},{$num}";
			}
		//设置tag查询条件
	//	if (!empty ($tags)) {
			$tag = " AND (LOCATE(',{$tags},',CONCAT(',',nns_tag))>0 OR nns_tag='' OR ISNULL(nns_tag) ) ";
		//} else {
		//	$tag = "";
	//	}
		//指定字段为空则全部查询
		if (empty ($fields)) {
			$field = "*";
		} else {
			$field = implode(',', $fields);
		}
		//判断是模糊查询还是等于查询
		if($if_like==1){
			$category_where="nns_category_id='{$category_id}'";
		}else{
			$category_where="nns_category_id like '{$category_id}%'";
		}
		$sql = "select {$field} from nns_topic_item where nns_audit='1' AND nns_topic_id='{$topic_id}' AND {$category_where} {$tag} " . self :: $order[$order] . " {$limit}";

		$result = nl_query_by_db($sql, $db);
		if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
		
		return $result;
	}
	/**
	 * 从缓存直接读取栏目下信息内容列表
	 */
	static private function _epg_get_topic_item_list_cache($dc, $topic_id, $category_id, $tags, $since = null, $num, $order, $policy = NL_DC_AUTO, $if_like=1,$fields) {
		$db = $dc->db();
		if ($since === null) {
			$limit = "";
		} else
			if (!empty ($since) && empty ($num)) {
				$limit = " LIMIT {$since}";
			} else {
				$limit = " LIMIT {$since},{$num}";
			}
		//if (!empty ($tags)) {
			$tag = " AND (LOCATE(',{$tags},',CONCAT(',',nns_tag))>0 OR nns_tag='' OR ISNULL(nns_tag)) ";
		//} else {
		//	$tag = "";
		//}
		//判断是模糊查询还是等于查询
		if($if_like==1){
			$category_where="nns_category_id='{$category_id}'";
		}else{
			$category_where="nns_category_id like '{$category_id}%'";
		}
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql = "select nns_id,DATE(nns_create_time) as nns_create_time_ex from nns_topic_item where  nns_audit='1' AND nns_topic_id='{$topic_id}' AND {$category_where} {$tag} " . self :: $order[$order] . " {$limit} ";
		}else{
			$sql = "select nns_id from nns_topic_item where  nns_audit='1' AND nns_topic_id='{$topic_id}' AND {$category_where} {$tag} " . self :: $order[$order] . " {$limit} ";
		}
//		echo '<br>'.$sql;die;
		$md5_sql = md5($sql);
		if($dc->is_cache_enabled()){//开启缓存
			$cache = $dc->cache();
			//获取key
			$key = $cache->get('topic|#' . $topic_id .'|#'. $category_id);
			//获取ids的cache，是一个二维数组
			$nns_ids = $cache->get($key . $md5_sql);
			//如果没有取到，则判断是否需要从数据库里去获取
			if (empty ($nns_ids)) {
				if ($policy == NL_DC_AUTO) {
					if (empty ($key))
						$key = 'topic_' . time();
					$cache->set('topic|#' . $topic_id ."|#". $category_id, $key);
					$result = nl_query_by_db($sql, $db);
					if ($result !== false) {
						$nns_ids = $result;
						$cache->set($key . $md5_sql, $result);
						self :: _epg_set_topic_item_list_cache($dc, $topic_id, $category_id, $tags, $since, $num, $order);
					}
				} else {
					return NULL;
				}
			}
		}elseif ($policy == NL_DC_AUTO) {//没有开启但是需要继续从数据库获取
					$nns_ids = nl_query_by_db($sql, $db);
				}
		$ids = array ();
		if(is_array($nns_ids)){
			foreach ($nns_ids as $id) {
				$ids[] = $id['nns_id'];
			}
		}
		return self :: _get_cache_by_ids($dc, $ids, $fields, $policy);
	}
	/**
	 * 设置缓存
	 */
	static private function _epg_set_topic_item_list_cache($dc, $topic_id, $category_id, $tags, $since = null, $num, $order) {
		if(!$dc->is_cache_enabled()) return null;
		$cache = $dc->cache();
		$db = $dc->db();
		if ($since === null) {
			$limit = "";
		} else
			if (!empty ($since) && empty ($num)) {
				$limit = " LIMIT {$since}";
			} else {
				$limit = " LIMIT {$since},{$num}";
			}
		if (!empty ($tags)) {
			$tag = " AND (LOCATE(',{$tags},',CONCAT(',',nns_tag))>0  OR nns_tag='' OR ISNULL(nns_tag))";
		} else {
			$tag = "";
		}
		$sql = "select nns_id,DATE(nns_create_time) as nns_create_time_ex from nns_topic_item where nns_audit='1' AND nns_topic_id='{$topic_id}' AND nns_category_id='{$category_id}' {$tag} " . self :: $order[$order] . " {$limit} ";
		$result = nl_query_by_db($sql, $db);
		if ($result === false) {
			return false;
		}
		$md5_sql = md5($sql);
		//获取key
		$key = $cache->get('topic|#' . $topic_id ."|#". $category_id);
		if (empty ($key)) {
			$key = 'topic_' . time();
			$cache->set('topic|#' . $topic_id ."|#". $category_id, $key);
		}
		//设置cache
		$cache = $cache->set($key . $md5_sql, $result);
		return $cache;
	}
	/**
	 * 删除缓存，这个方法是公用的，删除指定包下的指定栏目的缓存
	 * @param cache $cache
	 * @param string $topic_id
	 * @param string $category_id
	 */
	static private function _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id) {
		if($dc->is_cache_enabled())
		return $dc->cache()->delete("topic|#" . $topic_id ."|#". $category_id);
	}
	/**
	 * 前端使用
	 * 前端从DC模块获取栏目下及其子栏目信息内容列表 只读取前端列表需要的字段。
	 * @param dc DC模块
	 * @param string 信息包ID
	 * @param string 信息包栏目ID，默认为1000
	 * @param string  tag epg输出标识
	 * @param int 起始查询记录位置
	 * @param int 查询记录条数
	 * @param array $fields:查询字段一维索引数组(后面加的，需要传递完整的数据表字段)
	  *@param string 排序规则，NL_ORDER_NUM_ASC | NL_ORDER_NUM_DESC | NL_ORDER_TIME_ASC | NL_ORDER_TIME_DESC | NL_ORDER_CLICK_ASC | NL_ORDER_CLICK_DESC
	 * @param String 读取策略 NL_DC_AUTO| NL_DC_DB | NL_DC_CACHE
	 * @return *
	 * 			Array 信息包内容列表结果

	 * 			FALSE 查询失败
	 * 			TRUE  查询成功，但无数据
	 */
	static function epg_get_topic_item_list_by_child($dc, $topic_id, $category_id = 1000, $tag, $since, $num, $order = NL_ORDER_NUM_DESC, $policy = NL_DC_AUTO, $fields = array ()) {
		$result = "";
		switch ($policy) {
			case NL_DC_AUTO :
				$result = self :: _epg_get_topic_item_list_by_child_cache($dc, $topic_id, $category_id, $tag, $since, $num, $order, $policy, $fields);
				break;
			case NL_DC_DB :
				$result = self :: _epg_get_topic_item_list_by_child_db($dc->db(), $topic_id, $category_id, $tag, $since, $num, $order, $fields);
				break;
			case NL_DC_CACHE :
				$result = self :: _epg_get_topic_item_list_by_child_cache($dc, $topic_id, $category_id, $tag, $since, $num, $order, $policy, $fields);
				break;
		}
//		echo "<pre>";
//		print_r($result);die();
		return $result;
	}
	/**
	 * 从db获取栏目子孙列表
	 */
	static private function _epg_get_topic_item_list_by_child_db($db, $topic_id, $category_id, $tags, $since = null, $num, $order, $fields) {
		if ($since === null) {
			$limit = "";
		} else
			if (!empty ($since) && empty ($num)) {
				$limit = " LIMIT {$since}";
			} else {
				$limit = " LIMIT {$since},{$num}";
			}
		//if (!empty ($tags)) {
			$tag = " AND (LOCATE(',{$tags},',CONCAT(',',nns_tag))>0 OR nns_tag='' OR ISNULL(nns_tag)) ";
//		} else {
//			$tag = "";
//		}
		//指定字段为空则全部查询
		if (empty ($fields)) {
			$field = "*";
		} else {
			$field = implode(',', $fields);
		}
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql = "select {$field},DATE(nns_create_time) as nns_create_time_ex from nns_topic_item where nns_audit='1' AND  nns_topic_id='{$topic_id}' AND nns_category_id like '{$category_id}%' {$tag} " . self :: $order[$order] . " {$limit}";
		}else{
			$sql = "select {$field} from nns_topic_item where nns_audit='1' AND  nns_topic_id='{$topic_id}' AND nns_category_id like '{$category_id}%' {$tag} " . self :: $order[$order] . " {$limit}";
		}$result = nl_query_by_db($sql, $db);
		if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
		return $result;
	}
	/**
	 * 从cache获取栏目子孙列表
	 */
	static private function _epg_get_topic_item_list_by_child_cache($dc, $topic_id, $category_id, $tags, $since = null, $num, $order, $policy, $fields = array ()) {
		$db = $dc->db();
		if ($since === null) {
			$limit = "";
		} else
			if (!empty ($since) && empty ($num)) {
				$limit = " LIMIT {$since}";
			} else {
				$limit = " LIMIT {$since},{$num}";
			}
		//if (!empty ($tags)) {
			$tag = " AND (LOCATE(',{$tags},',CONCAT(',',nns_tag))>0 OR nns_tag='' OR ISNULL(nns_tag)) ";
//		} else {
//			$tag = "";
//		}
		//指定字段为空则全部查询
		if (empty ($fields)) {
			$field = "*";
		} else {
			$field = implode(',', $fields);
		}
		//获取所有的子栏目
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql = "select {$field},DATE(nns_create_time) as nns_create_time_ex from nns_topic_item where nns_audit='1' AND nns_topic_id='{$topic_id}' AND nns_category_id like '{$category_id}%' {$tag} " . self :: $order[$order] . " {$limit}";
		}else{
			$sql = "select {$field} from nns_topic_item where nns_audit='1' AND nns_topic_id='{$topic_id}' AND nns_category_id like '{$category_id}%' {$tag} " . self :: $order[$order] . " {$limit}";
		}
		$md5_sql = md5($sql);
		if($dc->is_cache_enabled()){
			$cache = $dc->cache();
			//获取栏目子孙key
			$key = $cache->get('posterity|#' . $topic_id ."|#". $category_id);
			$result = "";
			if (!empty ($key)) {
				//获取缓存
				$result = $cache->get($key . $md5_sql);
				//如果获取成功直接放回
				if (!empty ($result)){
					return $result;
				}else if($policy == NL_DC_AUTO){//如果没有获取成功则去设置缓存并从数据库读取返回
					$result = nl_query_by_db($sql, $db);
					if(is_array($result)){
						foreach ($result as $k=>$v){
								$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
							}
					}
					self :: _epg_set_topic_item_list_by_child_cache($dc,$topic_id, $category_id, $sql, $result);
				}
			}else if($policy == NL_DC_AUTO){
				//如果策略需要继续从数据库获取则继续
				$result = nl_query_by_db($sql, $db);
								if(is_array($result)){
						foreach ($result as $k=>$v){
								$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
							}
					}
			}
		}else if($policy == NL_DC_AUTO){
			//如果策略需要继续从数据库获取则继续
			$result = nl_query_by_db($sql, $db);
							if(is_array($result)){
						foreach ($result as $k=>$v){
								$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
							}
					}
		}else{
			$result=null;
		}
		if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
		return $result;
	}
	/**
	 * 设置子孙列表缓存
	 * 这里采用传递sql的原因是为了统一sql，不会让那种本来sql意思一样但是就是因为多了一个空格而导致在缓存取不出。
	 */
	static private function _epg_set_topic_item_list_by_child_cache($dc,$topic_id, $category_id, $sql, $result) {
		if(!$dc->is_cache_enabled()) return null;
		$cache = $dc->cache();
		$md5_sql = md5($sql);
		//获取栏目的子孙key
		$key = $cache->get('posterity|#' . $topic_id ."|#". $category_id);
		if (empty ($key)) {
			$key = 'posterity|#' . $topic_id ."|#". $category_id;
			$cache->set('posterity|#' . $topic_id ."|#". $category_id, $key);
		}
		//设置cache
		$cache = $cache->set($key . $md5_sql, $result);
		return $cache;
	}
	/**
	 * 删除栏目的子孙列表数据,只要有任何数据有修改都需要来调用此方法
	 * @param CACHE $cache
	 * @param string $topic_id
	 * @param string $category_id
	 */
	static private function _epg_del_topic_item_list_by_child_cache($dc, $topic_id, $category_id) {
		//获取栏目的子孙key
		if($dc->is_cache_enabled())
		return $dc->cache()->delete('posterity|#' . $topic_id ."|#". $category_id);
	}
	/**
	 * 前端使用
	 * 前端从DC模块查询信息内容列表 只返回前端列表需要的字段。
	 * @param dc DC模块
	 * @param string  tag epg输出标识
	 * @param int 起始查询记录位置
	 * @param int 查询记录条数
	 * @param array 查询参数组
	 * @param array $fields:需要获取的字段索引数组
	 * @param string 排序规则，NL_ORDER_NUM_ASC | NL_ORDER_NUM_DESC | NL_ORDER_TIME_ASC | NL_ORDER_TIME_DESC | NL_ORDER_CLICK_ASC | NL_ORDER_CLICK_DESC
	 * @return *
	 * 			Array 信息包内容列表结果
	 * 			FALSE 查询失败
	 * 			TRUE  查询成功，但无数据
	 */
	static function epg_get_search_topic_list($dc, $tags, $since = null, $num, $search_params, $order = NL_ORDER_NUM_DESC, $fields = array ()) {
		$db = $dc->db();
		if ($since === null) {
			$limit = "";
		} else {
			$limit = " LIMIT {$since},{$num}";
		}
		$com_sql = self :: com_sql($search_params);
		if (!empty ($com_sql))
			$com_sql = " where " . $com_sql;
		if (empty ($fields)) {
			$field = "*";
		} else {
			$field = implode(',', $fields);
		}
		if (!empty ($tags)) {
			$tag = " AND (LOCATE(',{$tags},',CONCAT(',',nns_tag))>0 OR nns_tag='' OR ISNULL(nns_tag)) ";
		} else {
			$tag = "";
		}
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql = "SELECT {$field},DATE(nns_create_time) as nns_create_time_ex FROM nns_topic_item {$com_sql} {$tag} AND nns_audit='1' " . self :: $order[$order] . " {$limit}";
		}else{
			$sql = "SELECT {$field} FROM nns_topic_item {$com_sql} {$tag} AND nns_audit='1' " . self :: $order[$order] . " {$limit}";
		}
		$result = nl_query_by_db($sql, $db);
		if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
		return $result;
	}

	/**
	 *从DC模块获取信息包内容列表数量
	 * @param dc DC模块
	 * @param array 查询参数组
			Array(
				'topic_id'=>信息包ID ，用“#”隔开  =查询 and连接
									用“|”隔开  =查询 OR连接
				'category_id'=>信息栏目ID ，用“#”隔开  =查询 and连接
									用“|”隔开  =查询 OR连接
				'title'=>信息标题，LIKE查询
				'subtitle'=>信息副标题，LIKE查询
				'keyword'=>信息关键字，关键字用“#”隔开  =查询 and连接
									用“|”隔开  =查询 OR连接
				'tag'=>信息EPG标识，TAG标识用“#”隔开  =查询 and连接
									用“|”隔开    =查询 OR连接
				'summary'=>信息摘要，LIKE查询
				'link_type'=>信息是否外链，=查询
				'source'=>信息来源，LIKE查询
				'content'=>信息内容，LIKE查询
				"audit"=>0/1是否审核
			)
	 * @return *
	 *
	 * 			FALSE 查询失败
	 * 			int  查询数量
	 */
	static function count_topic_item_list($dc, $search_params) {
		return self :: _count_topic_item_list_by_db($dc->db(), $search_params);
	}
	/**
	 * 从db 获取信息包内容列表数量
	 */
	static private function _count_topic_item_list_by_db($db, $search_params) {
		$com_sql = self :: com_sql($search_params);
		if (!empty ($com_sql))
			$com_sql = " where " . $com_sql;
		$sql = "SELECT count(1) as num FROM nns_topic_item {$com_sql}";
//		echo $sql;die();
		$result = nl_query_by_db($sql, $db);
		if ($result !== false && $result !== true) {
			return $result[0]['num'];
		}
		if ($result === true) {
			return 0;
		}
		return false;
	}
	/**
		 *从DC模块获取指定栏目子孙内容类表数量
		 * @param dc DC模块
		 * @param “topic_id”=>信息包ID ，
		 * @param “category_id”=>信息栏目ID ，可以不传递，不传递就是只查询属于这个包的内容数目
		 *
		 * @param array 查询参数组
				Array(
					“title”=>信息标题，LIKE查询
					“subtitle”=>信息副标题，LIKE查询
					“keyword”=>信息关键字，关键字用“#”隔开  =查询 and连接
																					用“|”隔开  =查询 OR连接
					“tag”=>信息EPG标识，TAG标识用“#”隔开  =查询 and连接
												用“|”隔开    =查询 OR连接
					“summary”=>信息摘要，LIKE查询
					“link_type”=>信息是否外链，=查询
					“source”=>信息来源，LIKE查询
					“content”=>信息内容，LIKE查询
					 "audit"=>0/1是否审核
	)

		 * @return
		 * 			FALSE 查询失败
		 * 			int  查询数量
		 */
	static public function count_topic_item_list_by_child($dc, $topic_id, $category_id, $search_params) {
		$com_sql = self :: com_sql($search_params);
		if(!empty($category_id)){
			$category_where="AND nns_category_id like '{$category_id}%'";
		}else{
			$category_where="";
		}
		$com_sql=trim($com_sql);
		if(strpos($com_sql, "and ")===0){
			$com_sql=ltrim($com_sql,"and ");
		}
		if(strpos($com_sql, "or ")===0){
			$com_sql=ltrim($com_sql,"or ");
		}
		if(strpos($com_sql, "AND ")===0){
			$com_sql=ltrim($com_sql,"AND ");
		}
		if(strpos($com_sql, "OR ")===0){
			$com_sql=ltrim($com_sql,"OR ");
		}
		$sql = "SELECT count(1) as num FROM nns_topic_item where nns_topic_id='{$topic_id}' {$category_where} AND {$com_sql}";
		$result = nl_query_by_db($sql, $dc->db());
		if ($result !== false && $result !== true) {
			return $result[0]['num'];
		}
		if ($result === true) {
			return 0;
		}
		return false;
	}
	/**
		 *从DC模块获取信息包内容列表
		 * @param dc DC模块
		 * @param string 信息包ID
		 * @param string 信息包栏目ID
		 * @param int 起始查询记录位置
		 * @param int 查询记录条数
		 * @param array 查询参数组
		 * @return *
		 * 			Array 信息包内容列表结果
		 * 			FALSE 查询失败
		 * 			TRUE  查询成功，但无数据
		 */
	static function get_topic_item_list($dc, $topic_id, $category_id, $since, $num, $search_params = array (), $order = NL_ORDER_NUM_DESC) {
		return self::_get_topic_item_list_by_db($dc->db(), $topic_id, $category_id, $since, $num, $search_params, $order);
	}

	static private function _get_topic_item_list_by_db($db, $topic_id = null, $category_id = null, $since = null, $num = 10, $search_params = null, $order = NL_ORDER_NUM_DESC) {
		if ($since === null) {
			$limit = "";
		} else {
			$limit = " LIMIT {$since},{$num}";
		}
		$com_sql = self :: com_sql($search_params);
		if (!empty ($com_sql))
			$com_sql = " AND " . $com_sql;
		//组装topic_id和category_id
		if (strpos($topic_id, '#') || strpos($topic_id, "|")) {
			$where_topic_id = self :: where_part(array (
				"topic_id" => $topic_id
			));
		} else {
			$where_topic_id = "nns_topic_id='{$topic_id}'";
		}
		if (strpos($category_id, '#') || strpos($category_id, "|")) {
			$where_category_id = self :: where_part(array ( "category_id" => $category_id ));
			
		} else {
			$where_category_id = "nns_category_id='{$category_id}'";
		}
		if($order == NL_ORDER_TIME_AND_NUM_DESC){
			$sql = "SELECT *,DATE(nns_create_time) as nns_create_time_ex FROM nns_topic_item where {$where_category_id} and  {$where_topic_id}  {$com_sql}  " . self :: $order[$order] . " {$limit}";
		}else{
			$sql = "SELECT * FROM nns_topic_item where {$where_category_id} and  {$where_topic_id}  {$com_sql}  " . self :: $order[$order] . " {$limit}";
		}
		$result = nl_query_by_db($sql, $db);
		if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
		return $result;
	}
	/**
		 *从DC模块根据ID获取信息内容
		 * @param dc DC模块
		 * @param string 信息ID
		 * @param String 读取策略 NL_DC_AUTO| NL_DC_DB | NL_DC_CACHE
						默认为NL_DC_AUTO
			@param array	$fields:需要获取是字段一维索引数组
		 * @return *
		 * 			Array 单条信息内容结果
		 * 			FALSE 查询失败
		 * 			TRUE  查询成功，但无数据
		 */
	static function get_topic_item_info($dc, $id, $policy = NL_DC_AUTO,$fields=array()) {
		$result = "";
		switch ($policy) {
			case NL_DC_AUTO :
				$result = self :: _get_cache_by_ids($dc, array (
					$id
				), $fields, $policy);
				break;
			case NL_DC_DB :
				$result = self :: _get_topic_item_info_by_db($dc, $id,$fields);
				break;
			case NL_DC_CACHE :
				$result = self :: _get_cache_by_ids($dc, array (
					$id
				), $fields, $policy);
				break;
		}
		return array_pop($result);
	}
	static private function _get_topic_item_info_by_db($dc, $id,$fields=array()) {
		if(empty($fields)){
			$field="*";
		}else{
			$field=implode(',',$fields);
		}
		$sql = "select {$field} from nns_topic_item where nns_id='{$id}'";
		$result = nl_query_by_db($sql, $dc->db());
		if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
		return $result;
	}

	/**
	* 从DC模块添加一条信息
	* @param dc DC模块
	* @param string 信息包ID
	* @param string 信息包栏目ID
	* @param array 所需参数组,没有nns前缀
	* @param String 读取策略 NL_DC_AUTO| NL_DC_DB | NL_DC_CACHE 默认为NL_DC_DB
	* @return *
	* 			FALSE 添加失败
	* 			string 添加成功,返回添加成功后的信息ID
	*/
	static function add_topic_item($dc, $topic_id, $category_id, $params, $policy = NL_DC_AUTO) {
		$db = $dc->db();
		if ($dc == NULL || empty ($topic_id) || empty ($category_id))
			return FALSE;

		foreach ($params as $key => $val) {
			$search_params['nns_' . $key] = $val;
		}
		//判断是否传递了id
		if (!isset ($search_params['nns_id'])) {
			include_once '../../nn_cms_db/nns_common/nns_db_guid_class.php';
			$guid = new Guid();
			$search_params['nns_id'] = $guid->toString();
		}
		$search_params['nns_create_time'] = date('Y-m-d H:i:s');
		$search_params['nns_category_id'] = $category_id;
		$search_params['nns_topic_id'] = $topic_id;
		//获取所属栏目当前的对大order
		$sql = "select max(nns_order) as c from nns_topic_item where nns_topic_id='{$topic_id}' and nns_category_id='{$category_id}'";
		$r = nl_query_by_db($sql, $db);
		$order_num = (empty ($r[0]['c']) && $r[0]['c'] !== '0') ? 0 : $r[0]['c'] + 1;
		$search_params['nns_order'] = $order_num;
		$sql = self :: _set_insert_sql($search_params, 'nns_topic_item');
		$result = nl_execute_by_db($sql, $db);
		if ($result === false) {
			return false;
		}
		//删除栏目缓存
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		self :: _epg_del_topic_item_list_by_child_cache($dc, $topic_id, $category_id);
		//删除父辈节点缓存的子孙列表节点
		self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
		//添加id缓存
		if ($policy == NL_DC_AUTO) {
			self :: _set_cache_by_ids($dc, $ids = array (
				$search_params['nns_id']
			));
		}
		return $search_params['nns_id'];
	}

	/**
		 * 从DC模块修改信息包内容
		 * @param dc DC模块
		 * @param string 信息包内容ID
		 * @param array 所需参数组
		 * @param String 读取策略 NL_DC_AUTO| NL_DC_DB | NL_DC_CACHE 默认为NL_DC_DB
		 * @return *
		 * 			FALSE 修改失败
		 * 			TRUE  修改成功
		 */
	static public function modify_topic_item($dc, $id, $params, $policy = NL_DC_DB) {
		$db = $dc->db();
		$sql = self :: _set_update_sql($params, "nns_topic_item") . " where nns_id='{$id}'";
		$result = nl_execute_by_db($sql, $db);
		if ($result) {
			self :: _set_cache_by_ids($dc, array (
				$id
			));
			self :: _del_keys_by_ids($dc, array (
				$id
			));
		}
		$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
		$r = nl_query_by_db($sql, $db);
		$topic_id = $r[0]['nns_topic_id'];
		$category_id = $r[0]['nns_category_id'];
		//删除包缓存，这是后来上线的时候修改epg没法重置缓存加的，因为之前没有说包下面可以直接放内容
		//一下2个if是后来加的
//		if($category_id==1000){
//			$category_id='';
//		}
//		if(empty($category_id)){
//			$category_id=1000;
//		}
		if($dc->is_cache_enabled()){
			$cache=$dc->cache();
			$cache->delete('topic|#' . $topic_id .'|#'. $category_id);
			$cache->delete('topic|#' . $topic_id .'|#');
		}
		//删除父辈节点缓存的子孙列表节点
		self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
		//删除栏目缓存
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		//后来加的
		self :: _epg_del_topic_item_list_by_child_cache($dc, $topic_id, $category_id);
		//更新id记录缓存
		self :: _del_cache_by_ids($dc, array (
			$id
		), 1);
		return $result;
	}

	/**
	* 从DC模块修改信息包内容
	* @param dc DC模块
	* @param array 信息ID组
	* @param String 读取策略 NL_DC_AUTO| NL_DC_DB | NL_DC_CACHE 默认为NL_DC_DB
	* @return *
	*			ARRAY(
					“信息ID”=>array 信息内容
					“信息ID”=>array 信息内容
					) 查询成功
	* 			FALSE 查询失败
	* 			TRUE  操作成功，但无数据
	*/
	static public function get_topic_item_by_ids($dc, $ids, $policy = NL_DC_DB) {
		switch ($policy) {
			case NL_DC_AUTO :
				$result = self :: _get_cache_by_ids($dc, $ids, null, $policy);
				break;
			case NL_DC_DB :
				$result = self :: _get_topic_item_info_by_db($dc, $ids);
				break;
			case NL_DC_CACHE :
				$result = self :: _get_cache_by_ids($dc, $ids, null, $policy);
				break;
		}
		if ($result === false) {
			return false;
		}
		if ($result === true) {
			return true;
		}
		$r = array ();
		foreach ($result as $val) {
			$r[$val['nns_id']] = $val;
		}
		return $r;
	}
	static private function _get_topic_item_by_ids_by_db($dc, $ids) {
		$nns_ids = " in (";
		foreach ($ids as $id) {
			$ids .= "'{$id}',";
		}
		$nns_ids = rtrim($nns_ids, ',');
		$nns_ids .= ") ";
		$sql = "select * from nns_topic_item where {$id}";
		$result = nl_query_by_db($sql, $dc->db());
						if(is_array($result)){
						foreach ($result as $k=>$v){
								$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
							}
					}
		return $result;
	}
	/**
	* 从DC模块删除信息内容
	* @param dc DC模块
	* @param string 信息内容ID
	* @param String 读取策略 NL_DC_AUTO| NL_DC_DB | NL_DC_CACHE 默认为NL_DC_DB
	* @return *
	* 			FALSE 删除失败
	* 			TRUE  删除成功
	*/
	static public function delete_topic_item($dc, $id, $policy = NL_DC_DB) {
		$db = $dc->db();
		$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
		$re = nl_query_by_db($sql, $db);
		$sql = "delete from nns_topic_item where nns_id='{$id}'";
		$r = nl_execute_by_db($sql, $db);
		//置顶
		self :: update_topic_item_to_order_first($dc, $id);
		//删除对应的缓存
		self :: _del_cache_by_ids($dc, array (
			$id
		));
		//删除所在栏目缓存
		$topic_id = $re[0]['nns_topic_id'];
		$category_id = $re[0]['nns_category_id'];
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		self :: _epg_del_topic_item_list_by_child_cache($dc, $topic_id, $category_id);
		return $r;
	}
	/**
	* 从DC模块排序当前信息到最前
	* @param dc DC模块
	* @param string 信息内容ID
	* @return *
	* 			FALSE 排序失败
	* 			TRUE  排序成功
	*/
	static function update_topic_item_to_order_first($dc, $id, $order=NL_ORDER_NUM_DESC) {
		$db = $dc->db();
		//获取id的包id和栏目id
		$sql = "select nns_category_id,nns_topic_id,nns_order,nns_create_time,nns_audit from nns_topic_item 
				where nns_id='{$id}'";
		$r = nl_query_by_db($sql, $db);
		if(!is_array($r)){
			return false;
		}
		
		$c_o = $r[0]['nns_order'];
		//获取修改了order的记录id
		$sql = "select nns_id,nns_order from nns_topic_item where 
				nns_topic_id='{$r[0]['nns_topic_id']}'
				and nns_category_id='{$r[0]['nns_category_id']}'
				and nns_order>{$c_o}";
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql .= ' and nns_audit=\''.$r[0]['nns_audit'].'\' 
					and datediff(nns_create_time, \''.$r[0]['nns_create_time'].'\')=0';
		}
		$sql .= ' order by nns_order DESC';
		
		$ids = nl_query_by_db($sql, $db);
		if(!is_array($ids)){
			return false;
		}
		
		$max_order = $ids[0]['nns_order'];
		foreach ($ids as $val) {
			$ids_arr[] = $val['nns_id'];
		}
		
		//将所有比当前id对应的order大的都-1
		$sql = "update nns_topic_item set nns_order=nns_order-1 
				where nns_order>{$c_o} AND nns_category_id='{$r[0]['nns_category_id']}' 
				AND nns_topic_id='{$r[0]['nns_topic_id']}'";
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql .= ' and datediff(nns_create_time, \''.$r[0]['nns_create_time'].'\')=0';
		}
		$r = nl_execute_by_db($sql, $db);
		if ($r === false) {
			return false;
		}
		// 更新当前order值
		$sql = 'update nns_topic_item set nns_order='.$max_order.' where nns_id=\''.$id.'\'';
		$r = nl_execute_by_db($sql, $db);
		if ($r === false) {
			return false;
		}
		
		//更新所有order变动的缓存
		self :: _del_cache_by_ids($dc, $ids, 1);
		//删除栏目缓存
		$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
		$r = nl_query_by_db($sql, $db);
		$topic_id = $r[0]['nns_topic_id'];
		$category_id = $r[0]['nns_category_id'];
		//删除父辈节点缓存的子孙列表节点
		self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		return true;
	}

	/**
	 * 从DC模块排序当前信息到最末
	 * @param dc DC模块
	 * @param string 信息内容ID
	 * @return *
	 * 			FALSE 排序失败
	 * 			TRUE  排序成功
	 */
	static function update_topic_item_to_order_last($dc, $id, $order=NL_ORDER_NUM_DESC) {
	$db = $dc->db();
		//获取id的包id和栏目id
		$sql = "select nns_category_id,nns_topic_id,nns_order,nns_create_time,nns_audit from nns_topic_item 
				where nns_id='{$id}'";
		$r = nl_query_by_db($sql, $db);
		if(!is_array($r)){
			return false;
		}
		
		$c_o = $r[0]['nns_order'];
		//获取修改了order的记录id
		$sql = "select nns_id,nns_order from nns_topic_item where 
				nns_topic_id='{$r[0]['nns_topic_id']}'
				and nns_category_id='{$r[0]['nns_category_id']}'
				and nns_order<{$c_o}";
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql .= ' and nns_audit=\''.$r[0]['nns_audit'].'\' 
					and datediff(nns_create_time, \''.$r[0]['nns_create_time'].'\')=0';
		}
		$sql .= ' order by nns_order ASC';
		
		$ids = nl_query_by_db($sql, $db);
		if(!is_array($ids)){
			return false;
		}
		
		$min_order = $ids[0]['nns_order'];
		foreach ($ids as $val) {
			$ids_arr[] = $val['nns_id'];
		}
		
		//将所有比当前id对应的order大的都-1
		$sql = "update nns_topic_item set nns_order=nns_order+1 
				where nns_order<{$c_o} AND nns_category_id='{$r[0]['nns_category_id']}' 
				AND nns_topic_id='{$r[0]['nns_topic_id']}'";
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql .= ' and datediff(nns_create_time, \''.$r[0]['nns_create_time'].'\')=0';
		}
		$r = nl_execute_by_db($sql, $db);
		if ($r === false) {
			return false;
		}
		// 更新当前order值
		$sql = 'update nns_topic_item set nns_order='.$min_order.' where nns_id=\''.$id.'\'';
		$r = nl_execute_by_db($sql, $db);
		if ($r === false) {
			return false;
		}
		
		//更新所有order变动的缓存
		self :: _del_cache_by_ids($dc, $ids, 1);
		//删除栏目缓存
		$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
		$r = nl_query_by_db($sql, $db);
		$topic_id = $r[0]['nns_topic_id'];
		$category_id = $r[0]['nns_category_id'];
		//删除父辈节点缓存的子孙列表节点
		self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		return true;
	}

	/**
	 * 从DC模块对调2条信息的排序
	 * @param dc DC模块
	 * @param string 当前信息内容ID
	 * @param string 对调信息内容ID
	 * @return *
	 * 			FALSE 排序失败
	 * 			TRUE  排序成功
	 */
	static function update_topic_item_order_switch($dc, $id, $other_id) {
		$db = $dc->db();
		$sql = "select nns_order from nns_topic_item where nns_id='{$id}'";
		$c_order = nl_query_by_db($sql, $db);
		$sql = "select nns_order from nns_topic_item where nns_id='{$other_id}'";
		$o_order = nl_query_by_db($sql, $db);
		if ($c_order === true || $c_order === false || $o_order === true || $o_order === false) {
			return false;
		}
		$sql = "update nns_topic_item set nns_order={$o_order[0]['nns_order']} where nns_id='{$id}'";
		$r1 = nl_execute_by_db($sql, $db);
		$sql = "update nns_topic_item set nns_order={$c_order[0]['nns_order']} where nns_id='{$other_id}'";
		$r2 = nl_execute_by_db($sql, $db);
		
		if ($r1 && $r2) {
			//更新id记录缓存
			self :: _del_cache_by_ids($dc, array (
				$id,
				$other_id
			), 1);
			//删除栏目缓存
			$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
			$r = nl_query_by_db($sql, $db);
			$topic_id = $r[0]['nns_topic_id'];
			$category_id = $r[0]['nns_category_id'];
			//删除父辈节点缓存的子孙列表节点
			self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
			self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 从DC模块将信息包内容批量转移到另一栏目
	 * @param dc DC模块
	 * @param array  要转移的信息ID数组
	 * @param string 要转移到的栏目ID
	 * @return *
	 * 			FALSE 排序失败
	 * 			TRUE  排序成功
	 */
	static public function update_topic_item_category_to_other($dc, $ids, $other_category_id) {
		$db = $dc->db();
		if (!is_array($ids)) {
			return false;
		}
		//组装的ids字符串
		$in_ids = "";
		foreach ($ids as $id) {
			$r = self :: update_topic_item_to_order_first($dc, $id);
			$in_ids .= "'{$id}',";
			if ($r === fasle)
				return false;
		}
		//获取目标栏目的内容order最大值
		$sql = "select max(nns_order) as m from nns_topic_item";
		$r = nl_execute_by_db($sql, $db);
		$max = $r[0]['m'];
		$in_ids = rtrim($in_ids, ',');
		$sql = "update nns_topic_item set nns_category_id='{$other_category_id}' where nns_id in ({$in_ids})";
		$r = nl_execute_by_db($sql, $db);
		if ($r === false)
			return false;
		//将其置顶
		$i = empty ($max) ? 0 : 1;
		$ids = array_reverse($ids);
		foreach ($ids as $id) {
			$sql = "update nns_topic_item set nns_order=" . ($max + $i) . " where nns_id='{$id}'";
			$r = nl_execute_by_db($sql, $db);
			if ($r === false)
				return false;
			$i++;
		}
		//更新id记录缓存
		self :: _del_cache_by_ids($dc, $ids, 1);
		//删除源栏目缓存
		$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='" . $ids[0] . "'";
		$r = nl_query_by_db($sql, $db);
		$topic_id = $r[0]['nns_topic_id'];
		$category_id = $r[0]['nns_category_id'];
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		//删除目标栏目缓存
		$sql = "select nns_topic_id from nns_topic_item where nns_category_id='" . $other_category_id . "' limit 0,1";
		$r = nl_query_by_db($sql, $db);
		$topic_id = $r[0]['nns_topic_id'];
		$category_id = $other_category_id;
		//删除父辈节点缓存的子孙列表节点
		self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		return true;
	}

	/**
	* 从DC模块将信息内容增加一次点击数
	* @param dc DC模块
	* @param string信息ID
	* @return *
	* 			FALSE 修改失败
	* 			TRUE  修改成功
	*/
	static public function update_topic_item_click($dc, $id) {
		$db = $dc->db();
		$sql = "update nns_topic_item set nns_click=nns_click+1 where nns_id='{$id}'";
		$r = nl_execute_by_db($sql, $db);
		if ($r === false)
			return false;
		//更新id记录缓存
		self :: _del_cache_by_ids($dc, array (
			$id
		), 1);
		//删除栏目缓存
		$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
		$r = nl_query_by_db($sql, $db);
		$topic_id = $r[0]['nns_topic_id'];
		$category_id = $r[0]['nns_category_id'];
		//删除父辈节点缓存的子孙列表节点
		self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		return true;
	}

	/**
	 * 从DC模块审核信息内容
	 * @param dc DC模块
	 * @param string信息ID
	 * @param Boolean 是否审核 TRUE为审核 FALSE为取消审核
	 * @return *
	 * 			FALSE 修改失败
	 * 			TRUE  修改成功
	 */
	static public function update_topic_item_audit($dc, $bool, $id,$nns_audit_reason=null) {
		$db = $dc->db();
		//$audit = $bool === true ? 1 : 0;
		$sql = "update nns_topic_item set nns_audit='{$bool}',nns_audit_reason='{$nns_audit_reason}' where nns_id='{$id}'";
		$r = nl_execute_by_db($sql, $db);
		if ($r === false) {
			return false;
		}
		//设置id记录缓存
		self :: _set_cache_by_ids($dc, array (
			$id
		));
		//更新id记录缓存
		self :: _del_cache_by_ids($dc, array (
			$id
		), 1);
		//删除栏目缓存
		$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
		$r = nl_query_by_db($sql, $db);
		$topic_id = $r[0]['nns_topic_id'];
		$category_id = $r[0]['nns_category_id'];
		//删除父辈节点缓存的子孙列表节点
		self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
		self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		return true;
	}

	/**
	 * 构造 INSERT sql语句
	 * @param array $params  插入数据格式：字段名=>字段值
	 * @param string $table_name 表名字
	 */
	static private function _set_insert_sql($params, $table_name) {
		$ins_sql = 'INSERT INTO `' . $table_name . '` (';
		foreach ($params as $key => $val) {
			//yxt一下一行是对所有的html实体标签和单双引号进行转义
			$val = htmlentities($val, ENT_QUOTES, "UTF-8");
			$ins_key[] = $key;
			$ins_val[] = '\'' . $val . '\'';
		}
		$ins_sql .= implode(',', $ins_key) . ') VALUES(' . implode(',', $ins_val) . ')';
		return $ins_sql;
	}

	/**
	  * 构造 UPDATE sql语句
	  * @param array $params数据格式:字段名=>字段值
	  * @param string $table_name
	  */
	static private function _set_update_sql($params, $table_name) {
		$upd_sql = 'UPDATE `' . $table_name . '` SET ';
		foreach ($params as $key => $val) {
			//yxt一下一行是对所有的html实体标签和单双引号进行转义
			$val = htmlentities($val, ENT_QUOTES, "UTF-8");
			$sql_arr[] = 'nns_' . $key . '=\'' . $val . '\'';
		}
		$upd_sql .= implode(',', $sql_arr);
		return $upd_sql;
	}
	/**
	 * 传入记录包id和栏目id，循环删除父栏目的子孙查询列表缓存
	 * @param CACHA	$cache
	 * @param string	$topic_id:当前栏目所属包id
	 * @param string $category_id:当前栏目id
	 */
	static private function _del_cache_parent_posterity($dc, $topic_id, $category_id) {
		$count = strlen($category_id);
		for ($i = 4; $i < $count; $i = $i +3) {
			$sub_cat = substr($category_id, 0, $i);
			//调用删除方法删除
			self :: _epg_del_topic_item_list_by_child_cache($dc, $topic_id, $sub_cat);
		}
	}
	/**
	 * 组装where中两端都有%的like查询
	 * @param array $param:条件字段，格式为:字段=>值，的键值对
	 * @param string $term:连接条件OR或者AND
	 * @return string	string:返回的组装好的字符串用括号包含
	 */
	static function where_a_like($param = null, $log = "AND") {
		if (is_array($param)) {
			$str = "";
			foreach ($param as $key => $val) {
				$str = $str . ' nns_' . $key . " like '%" . $val . "%' " . $log . ' ';
			}
			$str = rtrim($str);
			$str = rtrim($str, $log);
			$str = ' ( ' . $str . ' ) ';
		} else {
			return "";
		}
		return $str;
	}
	/**
	 *  组装where左边%的like查询
	 * @param array $param:条件字段，格式为:字段=>值，的键值对
	 * @param string $term:连接条件OR或者AND
	 * @return string	string:返回的组装好的字符串用括号包含
	 */
	static function where_l_like($param = null, $log = "AND") {
		if (is_array($param)) {
			$str = "";
			foreach ($param as $key => $val) {
				$str = $str . ' nns_' . $key . " like '" . $val . "%' " . $log . ' ';
			}
			$str = rtrim($str);
			$str = rtrim($str, $log);
		} else {
			return "";
		}
		$str = ' ( ' . $str . ' ) ';
		return $str;
	}
	/**
	 * 对于采用#或者|分割的字符串组装sql
	 * @param array $param：传入的带有分割符号的字符串数组格式为：字段=>组合字符串，的键值对，一次可以传递多个
	 * @param string $log:连接逻辑条件
	 * @return array $parts:返回的每个元素都用括号包含了的
	 */
	static function where_part($param = null, $log = "AND") {
		if (is_array($param)) {
			$parts = '';
			foreach ($param as $key => $val) {
				$key = 'nns_' . $key;
				if (strpos($val, '#') || strpos($val, "|")) {
					$strarr = array ();
					if (strpos($val, "#")) {
						$ll = "AND";
						$strarr = explode('#', $val);
					} else {
						$ll = "OR";
						$strarr = explode('|', $val);
					}
					if ($key == "nns_tag") {
						$str = "(";
						foreach ($strarr as $s) {
							$str .= " LOCATE(',{$s},',CONCAT(',',nns_tag))>0 {$ll} ";
						}
						$str = rtrim($str);
						$str = rtrim($str, $ll);
						$str .= " OR ISNULL({$key}) OR {$key}='' ) {$log} ";
					} else
						if ($key == "nns_keyword") {
							$str = "( ";
							foreach ($strarr as $s) {
								$str .= " LOCATE(',{$s},',CONCAT(',',nns_keyword,','))>0 {$ll} ";
							}
							$str = rtrim($str);
							$str = rtrim($str, $ll);
						} else {
							$strarr[0] = "{$key}='" . $strarr[0];
							$str = ' ( ' . implode("' {$ll} {$key}='", $strarr);
							$str .= "' ) ";
						}
					$str=rtrim($str);
					$str=rtrim($str,$ll);
					$parts .= $str . ' ' . $log . ' ';
				} else {
					if ($key == 'nns_tag') {
						$str = " (LOCATE(',{$val},',CONCAT(',',nns_tag))>0 ";
						$str .= " OR ISNULL({$key}) OR {$key}='' )  {$log} ";
						$parts .= $str;
					} else
						if ($key == 'nns_keyword') {
							$str .= " LOCATE(',{$val},',CONCAT(',',nns_keyword,','))>0 ";
							$parts .= $str;
						} else {
							$parts .= $key . "='" . $val . "'" . ' ' . $log . ' ';
						}
				}
			}
			$parts = rtrim($parts);
			$parts = rtrim($parts, $log);
			return $parts;
		} else {
			return null;
		}
	}
	/**
	 * 采用等号相连的
	 * @param array $params
	 * @param string	$log:连接逻辑条件
	 * @return array $eq_a;
	 */
	static private function where_eq($params = array (), $log = "AND") {
		if (empty ($params))
			return false;
		$eq = '';
		foreach ($params as $key => $val) {
			$eq .= 'nns_' . $key . '=' . $val . ' ' . $log . ' ';
		}
		$eq = rtrim($eq);
		$eq = rtrim($eq, $log);
		return $eq;
	}
	/**
	 * 根据ids设置或者更改记录缓存
	 * @param array $ids
	 * @return bool true/false
	 */
	static private function _set_cache_by_ids($dc, $ids = array ()) {
		if(!$dc->is_cache_enabled()) return null;
		$db = $dc->db();
		$cache = $dc->cache();
		if (is_array($ids)) {
			foreach ($ids as $id) {
				$sql = "select * from nns_topic_item where nns_id='{$id}'";
				$result = nl_query_by_db($sql, $db);
				if ($result === false) {
					return false;
				} else
					if ($result !== true) {
						$cache->set($id, $result[0], self :: CACHE_TIME_OUT);
					}
			}
			return true;
		} else {
			return false;
		}
	}
	/**
	 * 通过ids获取缓存数据，根据策略决定是否在没有获取到的情况下去数据库读取
	 * @param dc $dc
	 * @param array $ids
	 * @param array $fields,为空则获取全部字段
	 * @param 策略类型 $policy
	 * @return array $data:返回二维数组
	 */
	static private function _get_cache_by_ids($dc, $ids = array (), $fields = array (), $policy = NL_DC_AUTO) {
		$data = array ();
		if (is_array($ids)) {
			foreach ($ids as $id) {
				if($dc->is_cache_enabled()){
					$result = $dc->cache()->get($id);
					if ($result) {
						if (!empty ($fields)) {
							foreach ($fields as $field) {
								$data[$id][$field] = $result[$field];
							}
						} else {
							$data[$id] = $result;
						}
					} else
						if ($policy === NL_DC_AUTO) {
							$sql = "select * from nns_topic_item where nns_id='{$id}'";
							$result = nl_query_by_db($sql, $dc->db());
							self :: _set_cache_by_ids($dc, $arr = array (
								$id
							));
							if ($result !== false && $result !== true) {
								if (!empty ($fields)) {
									foreach ($fields as $field) {
										$data[$id][$field] = $result[0][$field];
									}
								} else {
									$data[$id] = $result[0];
								}
							}
						}
				}else if($policy === NL_DC_AUTO){
					$sql = "select * from nns_topic_item where nns_id='{$id}'";
					$result = nl_query_by_db($sql, $dc->db());
				if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
					if ($result !== false && $result !== true) {
						if (!empty ($fields)) {
							foreach ($fields as $field) {
								$data[$id][$field] = $result[0][$field];
							}
						} else {
							$data[$id] = $result[0];
						}
					}
				}
			}
			return $data;
		} else {
			return false;
		}
	}
	/**
	 * 根据id删除或者更新记录缓存
	 * @param DC $dc对象
	 * @param array $ids
	 * @param 常量 $policy
	 */
	static private function _del_cache_by_ids($dc, $ids, $policy = NL_DC_AUTO) {
		if(!$dc->is_cache_enabled()) return null;
		//是否要更新缓存
		if ($policy === NL_DC_AUTO) {
			self :: _set_cache_by_ids($dc, $ids);
		} else {
			foreach ($ids as $id) {
				$dc->cache()->delete($id);
			}
		}
	}
	/**
	 * 上移，先判断是否已经到达了最上面，如果已经是最上面了就不在移动
	 * 如果上面还有信息，则将当前order+1,上面一个的order-1
	 * @param DC $dc
	 * @param string $id
	 * @return -1 已经处于最高层
	 * 					0执行失败
	 *   				1执行成功
	 */
	static public function item_up($dc, $id, $order=NL_ORDER_NUM_DESC) {
		$db = $dc->db();
		//获取信息所属的包id和栏目id和order
		$sql = "select nns_topic_id,nns_category_id,nns_order,nns_audit,nns_create_time 
				from nns_topic_item where nns_id='{$id}'";
		$result = nl_query_by_db($sql, $db);
		if ($result === false || $result === true) {
			return 0;
		}
		$topic_id = $result[0]['nns_topic_id'];
		$category_id = $result[0]['nns_category_id'];
		$order_num = $result[0]['nns_order'];
		$nns_audit = $result[0]['nns_audit']?$result[0]['nns_audit']:'0';
		$create_time = $result[0]['nns_create_time'];
		
		//判断是否有比当前order大的
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql = "select nns_id from nns_topic_item where 
					nns_topic_id='{$topic_id}' and nns_category_id='{$category_id}'
					and datediff(nns_create_time,'{$create_time}')=0
					and nns_audit='{$nns_audit}' and nns_order>{$order_num}
					order by nns_order ASC limit 0,1";
		}else{
			$sql = "select nns_id from nns_topic_item where 
					nns_topic_id='{$topic_id}' and nns_category_id='{$category_id}'
					and nns_order>{$order_num} order by nns_order ASC limit 0,1";
		}
		
		$r = nl_query_by_db($sql, $db);
		if ($r === true) {
			return -1;
		}
		elseif ($r === false) {
			return 0;
		}
		$r = self :: update_topic_item_order_switch($dc, $id, $r[0]['nns_id']);
		if ($r === false) {
			return 0;
		}
		return 1;
	}
	/**
	 * 下移，先判断当前的信息是否已经是处于最底层了，如果是，则不做操作
	 * 如果下面还有记录，则将当前的order-1，下一个的order+1
	 * @param DC $dc
	 * @param string $id
	 * @return -1 已经处于最低层
	* 					0执行失败
	*   				1执行成功
	 */
	static public function item_down($dc, $id, $order=NL_ORDER_NUM_DESC) {
		$db = $dc->db();
		//获取信息所属的包id和栏目id和order
		$sql = "select nns_topic_id,nns_category_id,nns_order,nns_audit,nns_create_time 
				from nns_topic_item where nns_id='{$id}'";
		$result = nl_query_by_db($sql, $db);
		if ($result === false || $result === true) {
			return 0;
		}
		
		$topic_id = $result[0]['nns_topic_id'];
		$category_id = $result[0]['nns_category_id'];
		$order_num = $result[0]['nns_order'];
		$nns_audit = $result[0]['nns_audit']?$result[0]['nns_audit']:'0';
		$create_time = $result[0]['nns_create_time'];
		
		//判断是否有比当前order小的
		if($order==NL_ORDER_TIME_AND_NUM_DESC){
			$sql = "select nns_id from nns_topic_item where 
					nns_topic_id='{$topic_id}' and nns_category_id='{$category_id}'
					and datediff(nns_create_time,'{$create_time}')=0
					and nns_audit='{$nns_audit}' and nns_order<{$order_num}
					order by nns_order DESC limit 0,1";
		}else{
			$sql = "select nns_id from nns_topic_item where 
					nns_topic_id='{$topic_id}' and nns_category_id='{$category_id}'
					and nns_order<{$order_num} order by nns_order DESC limit 0,1";
		}
		$r = nl_query_by_db($sql, $db);
		if ($r === true) {
			return -1;
		}
		elseif ($r === false) {
			return 0;
		}
		$r = self :: update_topic_item_order_switch($dc, $id, $r[0]['nns_id']);
		if ($r === false) {
			return 0;
		}
		return 1;
	}
	/**
	 * 设置ids在哪些缓存key里面有缓存
	 * @param array $ids:一维索引数组
	 * @param string $key
	 */
	static private function _set_ids_have_key($dc, $ids = array (), $key = '') {
		if(!$dc->is_cache_enabled()) return null;
		if (empty ($ids) || empty ($key)) {
			return false;
		}
		$cache = $dc->cache();
		foreach ($ids as $id) {
			//获取字段已经缓存的key
			$keys = $cache->get($id . '_key');
			if (!empty ($keys)) {
				$keys[] = $key;
			} else {
				$key = array ();
				$keys[] = $key;
			}
			$cache->set($id . '_key', $key, self :: CACHE_TIME_OUT);
		}
	}
	/**
	 * 根据ids删除对应的keys
	 * @param array $ids:一维索引数组
	 * @param array $keys:如果为空则全部删除,传入一维数组(传入的是需要重新设置的id)
	 */
	static private function _del_keys_by_ids($dc, $ids, $keys = array ()) {
		if(!$dc->is_cache_enabled()) return null;
		if (!is_array($ids)) {
			return false;
		}
		$cache = $dc->cache();
		foreach ($ids as $id) {
			if (empty ($keys)) {
				$cache->delete($id . '_key');
			} else {
				$c_keys = $cache->get($id . '_key');
				$c_n_keys = array_diff($c_keys, $keys);
				$cache->set($id . '_key', $c_n_keys);
			}
		}
	}
	/**
	 * 按照时间查询处于两个时间段之间的信息
	 * @param DC $dc
	 * @param array $search_fields:除开时间以外的条件，键名为完整字段，键值为字段值
	 * @param string	$s_time
	 * @param string $etime
	 * @param array	$fiels
	 * @return bool false:查询失败，true没有结果集，array：结果集二维数组
	 */
	static public function search_by_time($dc,$search_fields=array(),$topic_id, $category_id, $s_time, $e_time, $since = null, $num = 10, $order = NL_ORDER_NUM_DESC, $fields = array ()) {
		//判断参数
		if(empty($search_fields)){
			$search_where="";
		}else{
			$search_where=self::com_sql($search_fields).' and ';
		}
		if ($since === null) {
			$limit = "";
		} else {
			$limit = " LIMIT {$since},{$num}";
		}
		if (empty ($fields)) {
			$field = "*";
		} else {
			$field = implode(',', $field);
		}
		//组装时间条件
		if ($s_time === null && $e_time === null) {
			$time = "";
		} else
			if ($s_time === null) {
				$time = " and nns_create_time<='{$e_time}'";
			} else
				if ($e_time === null) {
					$time = " and nns_create_time>='{$s_time}'";
				} else {
					$time = " and nns_create_time>='{$s_time}' and nns_create_time<='{$e_time}'";
				}
		$sql = "select {$field} from nns_topic_item where {$search_where} nns_topic_id='{$topic_id}' and nns_category_id='{$category_id}' {$time} " . self :: $order[$order] . " {$limit}";
		$result=nl_query_by_db($sql, $dc->db());
		if(is_array($result)){
			foreach ($result as $k=>$v){
				$result[$k]['nns_title']=html_entity_decode($v['nns_title'],ENT_QUOTES,"UTF-8");
			}
		}
		return $result;
	}

	/**
	 * 组装where之后的部分条件匹配
	 * @param array $params
	 * @param string $log:连接逻辑条件
	 */
	static private function com_sql($params, $log = "AND") {
		//不是数组直接返回
		if (!is_array($params))
			return false;
		$sql = "";
		//获取有|和#分割的字段
		$part_arr = array_intersect_key($params, self :: $arr_com);
		$part_r = "";
		if (!empty ($part_arr)) {
			$part_r = self :: where_part($part_arr, $log);
		}
		//获取有like匹配的字段
		$like_arr = array_intersect_key($params, self :: $arr_like);
		$like_r = "";
		if (!empty ($like_arr)) {
			$like_r = self :: where_a_like($like_arr, $log);
		}
		//获取有=匹配的字段
		$eq_arr = array_intersect_key($params, self :: $arr_eq);
		$eq_r = "";
		if (!empty ($eq_arr)) {
			$eq_r = self :: where_eq($eq_arr, $log);
		}
		//组合剩余的sql
		$other = array_diff_key($params, self :: $arr_com, self :: $arr_like, self :: $arr_eq);
		if (!empty ($other)) {
			$other_sql = "";
			foreach ($other as $key => $val) {
				$other_sql .= 'nns_' . $key . "='{$val}' {$log} ";
			}
			$other_sql = trim($other_sql);
			$other_sql = rtrim($other_sql, $log);
		}
		$sql = "";
		if (!empty ($part_r)) {
			$sql = $part_r;
		}
		if (!empty ($like_r)) {
			$sql .= (empty ($sql) ? '' : $log) . $like_r;
		}
		if (!empty ($eq_r)) {
			$sql .= (empty ($sql) ? '' : $log) . $eq_r;
		}
		if (!empty ($other_sql)) {
			if(empty($sql)){
				$sql=$other_sql;
			}else{
				$sql = $sql . ' '.$log . ' ' . $other_sql;
			}
		}
		return $sql;
	}
	/**
		 * 输出sql语句（当前脚本所有调用本类生成的sql语句都在这里
		 * 调试使用
		 */
	public function add_sql($sql) {
		self :: $sql_arr[] = $sql;
	}
	/**
	 * 输出sql语句（当前脚本所有调用本类生成的sql语句都在这里）
	 * 调试使用
	 */

	/**
	 * 增加信息内容点击数
	 * @param DC $dc
	 * @param string	$item_id//信息内容id
	 * @return bool 执行情况
	 */
	static public function modify_item_click($dc, $item_id) {
		$db = $dc->db();
		$sql = "update nns_topic_item set nns_click=nns_click+1 where nns_id='{$id}'";
		$r = nl_execute_by_db($sql, $db);
		//如果执行成功则删除对应的缓存
		if ($r) {
			//删除记录缓存
			self :: _del_cache_by_ids($dc, array (
				$item_id
			));
			//查询包id和栏目id
			$sql = "select nns_topic_id,nns_category_id from nns_topic_item where nns_id='{$id}'";
			$r = nl_query_by_db($sql, $db);
			$topic_id = $r[0]['nns_topic_id'];
			$category_id = $r[0]['nns_category_id'];
			//删除父辈节点缓存的子孙列表节点
			self :: _del_cache_parent_posterity($dc, $topic_id, $category_id);
			//删除栏目缓存
			self :: _epg_del_cache_by_topic_category_id($dc, $topic_id, $category_id);
		}
		return $r;
	}
}
?>